package com.liveinstars.quhui.business.interest.service.impl;

import com.baidu.unbiz.easymapper.MapperFactory;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.liveinstars.api.dto.InterestDetailDto;
import com.liveinstars.api.dto.InterestDto;
import com.liveinstars.api.dto.InterestSimpleDto;
import com.liveinstars.api.dto.JoinInterest;
import com.liveinstars.api.post.dto.PostDetailDto;
import com.liveinstars.api.post.facade.IPostsApi;
import com.liveinstars.api.query.InterestQuery;
import com.liveinstars.quhui.business.interest.repository.facade.IInterestGroupMemberService;
import com.liveinstars.quhui.business.interest.repository.facade.IInterestGroupService;
import com.liveinstars.quhui.business.interest.repository.po.InterestGroup;
import com.liveinstars.quhui.business.interest.repository.po.InterestGroupMember;
import com.liveinstars.quhui.business.interest.service.InterestDomainService;
import com.onepiece.shipelves.common.exception.QuHuiRuntimeException;
import com.onepiece.shipelves.common.vo.Page;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 除了聚合根外聚合中还有领域服务service，也是主要的业务逻辑承载，负责聚合多个实体合作完成的业务逻辑，
 * 聚合中不要引用其他聚合的实体和值对象，以传参为主，为了以后拆分微服务，
 * 只用把应用接口层拆分出来。也不要调用其他聚合的领域服务，有application层调用
 */
@Service("interestService")
public class InterestDomainServiceImpl implements InterestDomainService {

    private final static Logger logger = LoggerFactory.getLogger(InterestDomainServiceImpl.class);

    @Autowired
    IInterestGroupService interestGroupService;

    @Autowired
    IInterestGroupMemberService interestGroupMemberService;


    @Autowired
    InterestFactory interestFactory;

    @Autowired

    IPostsApi postsApi;

    @Override
    public List<InterestSimpleDto> getAllInterest() {
        List<InterestGroup> list = interestGroupService.list();
        if(list != null && list.size() > 0){
            return interestFactory.getSimpleInterestDtos(list);
        }
        else {
            return null;
        }
    }

    @Override
    public Page<InterestDto> pageByQuery(InterestQuery query) {
        IPage<InterestGroup> iPage = interestGroupService.pageByQuery(query);
        Page<InterestDto> page = new Page<InterestDto>(interestFactory.getInterestDtos(iPage.getRecords()),
                Long.valueOf(iPage.getCurrent()).intValue(),
                Long.valueOf(iPage.getSize()).intValue(),
                Long.valueOf(iPage.getTotal()).intValue());

        return page;
    }

    @Override
    public List<InterestDto> getMyInterests(Integer userId) {
        List<InterestGroupMember> groupMemberList = interestGroupMemberService.listByUserId(userId, 0);
        if (CollectionUtils.isNotEmpty(groupMemberList)) {
            List<Integer> chatGroupIdList = Lists.newArrayList();
            HashMap<Integer,InterestGroupMember> groupMemberMap = Maps.newHashMap();
            groupMemberList.forEach(chatGroupMember -> {
                chatGroupIdList.add(chatGroupMember.getInterestGroupId());
                groupMemberMap.put(chatGroupMember.getInterestGroupId(), chatGroupMember);
            });
            List<InterestGroup> chatGroupList = interestGroupService.listByIds(chatGroupIdList);
            Map<Integer, Integer> chatGroupMemberCountMap = interestGroupMemberService.mapMemberCountByGroupIdList(chatGroupIdList);
            if (CollectionUtils.isNotEmpty(chatGroupList)) {
                MapperFactory.getCopyByRefMapper().mapClass(InterestGroup.class, InterestDto.class).register();
                List<InterestDto> groupP1List = chatGroupList.stream().map(p -> MapperFactory.getCopyByRefMapper().map(p,
                        InterestDto.class)).collect(Collectors.toList());
                for (InterestDto chatGroup : groupP1List) {
                    chatGroup.setUserCount(chatGroupMemberCountMap.get(chatGroup.getId()));
                }
                return groupP1List;
            } else {
                throw new QuHuiRuntimeException(QuhuiExceptionEnum.IS_EMPTY);
            }
        } else {
            return Collections.emptyList();
        }
    }

    @Override
    public List<InterestSimpleDto> getMyInterestsSimple(Integer userId) {

        List<InterestGroupMember> groupMemberList = interestGroupMemberService.listByUserId(userId, 0);
        if (CollectionUtils.isNotEmpty(groupMemberList)) {
            List<Integer> chatGroupIdList = Lists.newArrayList();
            groupMemberList.forEach(chatGroupMember -> {
                chatGroupIdList.add(chatGroupMember.getInterestGroupId());
            });
            List<InterestGroup> chatGroupList = interestGroupService.listByIds(chatGroupIdList);
            if (CollectionUtils.isNotEmpty(chatGroupList)) {
                MapperFactory.getCopyByRefMapper().mapClass(InterestGroup.class, InterestSimpleDto.class).register();
                List<InterestSimpleDto> groupP1List = chatGroupList.stream().map(p -> MapperFactory.getCopyByRefMapper().map(p,
                        InterestSimpleDto.class)).collect(Collectors.toList());
                return groupP1List;
            } else {
                throw new QuHuiRuntimeException(QuhuiExceptionEnum.IS_EMPTY);
            }
        } else {
            throw new QuHuiRuntimeException(QuhuiExceptionEnum.IS_EMPTY);
        }
    }

    @Override
    public InterestDetailDto getDetailById(Integer id) {
        InterestGroup interestGroup = interestGroupService.getById(id);
        if(interestGroup != null){
            ArrayList<Integer> ids = new ArrayList<>(Arrays.asList(id));
            Map<Integer, Integer> chatGroupMemberCountMap = interestGroupMemberService.mapMemberCountByGroupIdList(ids);
            InterestDetailDto interestDto = interestFactory.getInterestDto(interestGroup);
            interestDto.setUserCount(chatGroupMemberCountMap.get(id));

            return interestDto;
        }else {
            throw new QuHuiRuntimeException(QuhuiExceptionEnum.ENTITY_NOT_FOUND);
        }
    }

    @Override
    public Boolean joinInterest(JoinInterest interest, Integer userId) {
        if(interest.getInterestId() != null && !interest.getInterestId().equals(0)){
            return addInterestMember(interest.getInterestId(), userId);
        }else if(interest.getPostId() != null && !interest.getPostId().equals(0)){
            PostDetailDto postDetailDto = postsApi.getBy(interest.getPostId());
            if(postDetailDto != null){
                Integer interestId = postDetailDto.getInterestId();
                return addInterestMember(interestId, userId);
            }else {
                throw new QuHuiRuntimeException(QuhuiExceptionEnum.POST_NOT_FOUND);
            }
        }
        return false;
    }

    private Boolean addInterestMember(Integer interest, Integer userId) {
        InterestGroupMember member = new InterestGroupMember();
        member.setInterestGroupId(interest);
        member.setUserId(userId);
        boolean save = interestGroupMemberService.save(member);
        return save;
    }


}
